package com.boarsoft.boar.batch.biz;

import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.boar.batch.biz.BatchExecutionBiz;
import com.boarsoft.boar.batch.entity.BatchEvent;
import com.boarsoft.boar.batch.entity.BatchExecution;
import com.boarsoft.boar.batch.entity.BatchInfo;
import com.boarsoft.common.Util;
import com.boarsoft.common.biz.SimpleBizImpl;
import com.boarsoft.common.dao.PagedResult;

@Component
public class BatchExecutionBizImpl extends SimpleBizImpl implements BatchExecutionBiz {
	/** */
	// private SequenceGeneratorClient sequence;

	/**
	 * 插入一条新的任务组执行记录
	 * 
	 * @return 主键
	 */
	@Override
	@Transactional
	public String save(BatchExecution o) {
		if (Util.strIsEmpty(o.getId())) {
			dao.save(o);
		} else {
			dao.update(o);
		}
		return o.getId();
	}

	/**
	 * 根据任务组ID获取最后的一次执行记录。目的是检查有无正在执行的记录。
	 * 
	 * @param groupId
	 * @return
	 */
	@Override
	@Transactional(readOnly = true)
	public BatchExecution last(String infoId) {
		StringBuilder sb = new StringBuilder();
		sb.append("and infoId='").append(infoId);
		sb.append("' order by startTime desc");
		String wql = sb.toString();
		List<BatchExecution> lt = dao.list(BatchExecution.class, wql, 1, 1);
		if (lt.isEmpty()) {
			return null;
		}
		return lt.get(0);
	}

	@Override
	@Transactional(readOnly = true)
	public BatchExecution get(String id) {
		return dao.get(BatchExecution.class, id);
	}
	
	@Override
	@Transactional(readOnly = true)
	public List<BatchExecution> list(String[] ids) {
		StringBuilder sb = new StringBuilder();
		sb.append(" and id in (");
		for(int i = 0; i < ids.length; i++){
			if(i < ids.length - 1)
				sb.append("'").append(ids[i]).append("',");
			else
				sb.append("'").append(ids[i]).append("'");
		}
		sb.append(")");
		String wql = sb.toString();
		return dao.list(BatchExecution.class, wql);
	}

	@Override
	@Transactional(readOnly = true)
	public List<BatchExecution> list() {
		StringBuilder sb = new StringBuilder();
		sb.append(" and status in (").append(BatchExecution.STATUS_RUNNING);
		sb.append(", ").append(BatchExecution.STATUS_NEW);
		sb.append(", ").append(BatchExecution.STATUS_QUEUED);
		sb.append(", ").append(BatchExecution.STATUS_SUSPEND);
		sb.append(", ").append(BatchExecution.STATUS_STOPPING).append(")");
		String wql = sb.toString();
		return dao.list(BatchExecution.class, wql);
	}

	@Override
	@Transactional(readOnly = true)
	public PagedResult<BatchExecution> list(String catalog, String key, String startTime, String endTime, int pageNo,
			int pageSize) {
		StringBuilder sb = new StringBuilder();
		sb.append("from ").append(BatchExecution.class.getName());
		sb.append(" where catalog = '").append(catalog).append("'");
		if (Util.strIsNotEmpty(key)) {
			sb.append(" and (code like '%").append(key);
			sb.append("'% or name like '%").append(key).append("%')");
		}
		if (Util.strIsNotEmpty(startTime)) {
			sb.append(" and startTime >= '").append(startTime).append("'");
		}
		if (Util.strIsNotEmpty(endTime)) {
			sb.append(" and endTime <= '").append(endTime).append("'");
		}
		String hql = sb.toString();
		int total = dao.getTotal("select count(id) ".concat(hql));
		List<BatchExecution> lt = dao.list(hql, pageNo, pageSize);
		return new PagedResult<BatchExecution>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional(readOnly = true)
	public PagedResult<BatchExecution> list(String infoId, String startTime, String endTime, int pageNo, int pageSize) {
		StringBuilder sb = new StringBuilder();
		sb.append("from ").append(BatchExecution.class.getName());
		sb.append(" where infoId = '").append(infoId).append("'");
		if (Util.strIsNotEmpty(startTime)) {
			sb.append(" and startTime >= '").append(startTime).append("'");
		}
		if (Util.strIsNotEmpty(endTime)) {
			sb.append(" and endTime <= '").append(endTime).append("'");
		}
		sb.append(" order by startTime desc");
		String hql = sb.toString();
		int total = dao.getTotal("select count(id) ".concat(hql));
		List<BatchExecution> lt = dao.list(hql, pageNo, pageSize);
		return new PagedResult<BatchExecution>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional(readOnly = true)
	public List<BatchExecution> list(short status) {
		StringBuilder sb = new StringBuilder("and status=").append(status);
		return dao.list(BatchExecution.class, sb.toString());
	}

	@Override
	@Transactional(readOnly = true)
	public PagedResult<Object[]> listExecuting(int pageNo, int pageSize) {
		StringBuilder sb = new StringBuilder();
		sb.append("from ").append(BatchExecution.class.getName()).append(" e, ");
		sb.append(BatchInfo.class.getName()).append(" i");
		sb.append(" where e.infoId = i.id and ");
		sb.append("e.status in (").append(BatchExecution.STATUS_NEW);
		sb.append(", ").append(BatchExecution.STATUS_QUEUED);
		sb.append(", ").append(BatchExecution.STATUS_RUNNING);
		sb.append(", ").append(BatchExecution.STATUS_STOPPING).append(")");
		sb.append(" order by e.infoId, e.startTime");
		String hql = sb.toString();
		int total = dao.getTotal("select count(e.id) ".concat(hql));
		List<Object[]> lt = dao.list(hql, pageNo, pageSize);
		return new PagedResult<Object[]>(total, lt, pageNo, pageSize);
	}
	
	@Override
	@Transactional
	public void delete(String id) {
		// 删除执行记录的相关事件
		StringBuilder sb = new StringBuilder();
		sb.append("delete from ").append(BatchEvent.class.getName());
		sb.append(" where exeId = '").append(id).append("'");
		dao.executeUpdate(sb.toString());
		// 删除执行记录
		dao.delete(BatchExecution.class, id);
	}
	
	@Override
	@Transactional
    public int updateStatusSuccess(String id) {
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(BatchExecution.class.getName()).append(" t");
        sb.append(" set t.status = ").append(3);
        sb.append(" where t.id = '").append(id).append("'");
        sb.append(" and t.addr = ");
        sb.append("(");
        sb.append("select concat('broadcast:',count(*)) from ").append(BatchEvent.class.getName()).append(" e");
        sb.append(" where e.exeId = '").append(id).append("'");
        sb.append(" and e.status = ").append(3);
        sb.append(")");
        this.dao.executeHql(sb.toString());
        return 0;
    }

	@Override
    @Transactional
    public int updateStatusFailed(String id) {
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(BatchExecution.class.getName()).append(" t");
        sb.append(" set t.status = ").append(4);
        sb.append(" where t.id = '").append(id).append("'");
        sb.append(" and t.addr = ");
        sb.append("(");
        sb.append("select concat('broadcast:',count(*)) from ").append(BatchEvent.class.getName()).append(" e");
        sb.append(" where e.exeId = '").append(id).append("'");
        sb.append(" and e.status in (3,4,7,8)");
        sb.append(")");
        this.dao.executeHql(sb.toString());
        return 0;
    }
    
}